#include "iic.h"


void iic_delay_us(unsigned char us)
{
	while(us--);
}

void iic_init_pins(void)
{

}

#ifdef SET_SDA_DIR
void set_sda_out(void)
{

}

void set_sda_in(void)
{

}
#endif


/**
 * 11 =>> 00
*/
unsigned char iic_start()
{
#ifdef SET_SDA_DIR
	set_sda_out();
#endif
	pin_clk_set;
	pin_sda_set;
	iic_delay_us(SPEED_US);
	if(!pin_sda_read)
	   return IIC_START_ERROR;
	pin_sda_clr;
	iic_delay_us(SPEED_US);
	if(pin_sda_read)
	   return IIC_START_ERROR;
	pin_clk_clr;
	return IIC_OK;
}

/**********************************************
* 00 => 11
**********************************************/
void iic_stop()
{
#ifdef SET_SDA_DIR
	set_sda_out();
#endif
	pin_clk_clr;
	pin_sda_clr;
	iic_delay_us(SPEED_US);
	pin_clk_set;
	pin_sda_set;
    iic_delay_us(SPEED_US);
}

void iic_send_ack(void)
{
	pin_sda_set;
    pin_clk_set;
    iic_delay_us(SPEED_US);
    pin_clk_clr;
}

void iic_send_nack(void)
{
	pin_sda_clr;
    pin_clk_set;
    iic_delay_us(SPEED_US);
    pin_clk_clr;
    // iic_delay_us(SPEED_US);
}

unsigned char iic_recv_ack(void)
{
	unsigned recv_ack;
#ifdef SET_SDA_DIR
	set_sda_in();
#endif
	pin_sda_set;
    pin_clk_set;
    iic_delay_us(SPEED_US);
	recv_ack = pin_sda_read;
    pin_clk_clr;
}


/**********************************************

**********************************************/
unsigned char iic_write_byte(unsigned char iic_byte)
{
    unsigned char i;
#ifdef SET_SDA_DIR
	set_sda_out();
#endif
    for(i=0;i<8;i++)
    {
        if(iic_byte & 0x80)
            pin_sda_set;
        else
            pin_sda_clr;

        pin_clk_set;
		iic_delay_us(SPEED_US);
        pin_clk_clr;
        iic_byte<<=1;
		iic_delay_us(SPEED_US);
    }
	return IIC_OK;
}

unsigned char iic_read_byte(void)
{
	unsigned char i,recv_byte=0;
#ifdef SET_SDA_DIR
	set_sda_in();
#endif
    for(i=0;i<8;i++ )
	{
        pin_clk_clr;
        iic_delay_us(SPEED_US);
		pin_clk_set;
        recv_byte<<=1;
        if(pin_sda_read)recv_byte++;  //if pin=1,recv_byte++
		iic_delay_us(SPEED_US);
    }
    return recv_byte;
}

// dev_addr need << 1
unsigned char iic_bus_read(unsigned char dev_addr, unsigned char reg_addr,unsigned char *reg_data, unsigned char cnt)
{
	unsigned char ierror = 0;
	unsigned char stringpos = 0;
    iic_start();
	iic_write_byte(dev_addr);   // send device addr and write signal
	iic_recv_ack();
	iic_write_byte(reg_addr);   // write register addr
	iic_recv_ack();

	iic_start();                // restart
	iic_write_byte(dev_addr+1); // send device addr and read signal
	iic_recv_ack();
	for (stringpos = 0; stringpos < (cnt-1); stringpos++)
	{
		reg_data[stringpos] = iic_read_byte();
		iic_send_ack();
	}
	reg_data[stringpos] = iic_read_byte();
	iic_send_nack();

	iic_stop();
	return ierror;
}

unsigned char iic_bus_write(unsigned char dev_addr, unsigned char reg_addr,unsigned char *reg_data, unsigned char cnt)
{
	unsigned char ierror = 0;

	unsigned char stringpos = 0;
	iic_start();
	iic_write_byte(dev_addr); // send device addr and write signal
	iic_recv_ack();

	iic_write_byte(reg_addr); // send register addr
	iic_recv_ack();
	for (stringpos = 0; stringpos < cnt; stringpos++)
    {
    	iic_write_byte(reg_data[stringpos]);
    	iic_recv_ack();
	}
    iic_stop();
	return ierror;
}
